
import { Client } from "@modelcontextprotocol/sdk/client/index.js"
import OpenAI from "openai";
import { SSEClientTransport } from "@modelcontextprotocol/sdk/client/sse.js";
import type { ChatCompletion, ChatCompletionMessageParam, ChatCompletionTool } from "openai/resources/chat/completions";
import { MessageQueue } from "../types/message-queue";

// 判断运行环境
const isNode = typeof window === 'undefined';
const API_BASE_URL = isNode ? (process.env.NEXT_PUBLIC_API_URL || 'http://localhost:3000') : '';

export class MCPClient {
  private mcp: Client;
  // private llm: OpenAI;
  private transport: SSEClientTransport;
  private tools: ChatCompletionTool[] = [];

  private historyMessages: MessageQueue = new MessageQueue();

  constructor() {
    // this.llm = new OpenAI({
    //   apiKey: process.env.OPENAI_API_KEY || 'sk-8f1676c9118b486889c3de773ca72633',
    //   baseURL: process.env.OPENAI_BASE_URL || 'https://api.deepseek.com/v1',
    // });
    console.log("process.env.NEXT_PUBLIC_MCP_SSE_URL", process.env.NEXT_PUBLIC_MCP_SSE_URL);
    this.transport = new SSEClientTransport(
      new URL(process.env.NEXT_PUBLIC_MCP_SSE_URL || "http://localhost:8000/sse"),
      // new URL("/api/mcp/sse")
    );

    this.mcp = new Client({
      name: "beidou-engine-mcp-client",
      version: "1.0.0"
    });
  }

  // mcp client connection
  public async init() {
    await this.mcp.connect(this.transport);
    const toolsResult = await this.mcp.listTools();
    this.tools = toolsResult.tools.map((tool) => {
      return {
        type: "function",
        function: {
          name: tool.name,
          description: tool.description,
          parameters: tool.inputSchema
        }
      } as ChatCompletionTool;
    });
    console.log(
      "Connected to server with tools:",
      this.tools.map((tool) => tool.function.name || "unnamed tool")
    );
  }

  public async close() {
    // 关闭mcp客户端
    await this.mcp.close();
  }

  /**
   * 聊天时自动处理工具调用
   * @param query 用户输入
   * @returns 
   */
  async processQuery(query:string): Promise<(ChatCompletionMessageParam | ChatCompletion)> {
    const messages: ChatCompletionMessageParam[] = [
      {
        role: "user",
        content: query
      }
    ]
    this.historyMessages.enqueue(messages[0]);


    // 【发起工具调用请求】要调用/api/chat
    const response = await fetch(`${API_BASE_URL}/api/chat`, {
      method: "POST",
      body: JSON.stringify({
        messages: this.historyMessages.getMessages(),
        tools: this.tools as ChatCompletionTool[],
      }),
      headers: {
        "Content-Type": "application/json"
      }
    });

    // 【接收工具调用响应】
    const responseData = await response.json();
    this.historyMessages.enqueue(responseData.choices[0].message);
    return responseData;


    // const message = responseData.choices[0].message;
    // if (message.content) {
    //   // 【存入历史消息】
    //   this.historyMessages.enqueue(message);
    // }

    // if (message.tool_calls) {
    //   // 【处理工具调用】
    //   const toolName = message.tool_calls[0].function.name;
    //   const toolArgs = message.tool_calls[0].function.arguments;

    //   // 【调用mcp工具】- 其实LLM已经决定好调用哪些工具了，这里只是使用mcp发起于远程函数调用
    //   const result = await this.mcp.callTool({
    //     name: toolName,
    //     arguments: JSON.parse(toolArgs)
    //   })

    //   // 【存入中间结果】
    //   this.historyMessages.enqueue({
    //     role: 'user',
    //     content: result.content as string,
    //   })

    //   // 【发起网络请求】
    //   const responseData = await fetch(`${API_BASE_URL}/api/chat`, {
    //     method: "POST",
    //     body: JSON.stringify({
    //       messages: this.historyMessages.getMessages(),
    //     }),
    //     headers: {
    //       "Content-Type": "application/json"
    //     }
    //   });
    //   // 【接收响应】
    //   const response = await responseData.json();
    //   this.historyMessages.enqueue(response.choices[0].message);
    // }

    // // 返回最后一条消息
    // return this.historyMessages.getMessages()[this.historyMessages.getMessages().length - 1];
  }

  /**
   * 【处理工具调用】 - 其实LLM已经决定好调用哪些工具了，这里只是使用mcp发起于远程函数调用
   * @param toolName 
   * @param toolArgs 
   */
  async callTool(toolName: string, toolArgs: any) {
    const result = await this.mcp.callTool({
      name: toolName,
      arguments: toolArgs
    })
    // 【存入中间结果】
    this.historyMessages.enqueue({
      role: 'user',
      content: result.content as string,
    })
    return result;
  }
  
}


// 初始化mcp客户端
const client = new MCPClient();
await client.init();

const result = await client.processQuery("帮我看看现在有哪些数据源？");
// console.log(result);

await client.close();

// const client = new Client(
//     {
//       name: "beidou-engine-mcp-client",
//       version: "1.0.0"
//     },
//     {
//       capabilities: {
//         prompts: {},
//         resources: {},
//         tools: {}
//       }
//     }
//   );
  
// let transport : SSEClientTransport = new SSEClientTransport(
//   new URL("http://localhost:8000/sse")
// )

// await client.connect(transport);

// // List prompts
// const prompts = await client.listPrompts();
// console.log("prompts", prompts);
// // List resources
// const resources = await client.listResources();
// console.log("resources", resources);
// const tools = await client.listTools();
// console.log("tools", tools);
  // Call a tool
//   const result = await client.callTool({
//     name: "example-tool",
//     arguments: {
//       arg1: "value"
//     }
//   });